package com.ztgf.sys.api.common.interceptor;

import com.alibaba.fastjson.JSON;
import com.ztgf.common.bo.HeadParamsBO;
import com.ztgf.common.constant.CommonParameter;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.sys.api.common.annotion.SysLogs;
import com.ztgf.sys.models.bo.SysLogSaveBO;
import com.ztgf.sys.models.dto.SysUserDTO;
import com.ztgf.sys.models.service.ISysLogService;
import com.ztgf.sys.models.service.ISysUserService;
import io.swagger.annotations.ApiOperation;
import org.apache.dubbo.config.annotation.DubboReference;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Method;

@Aspect
@Component
public class SysLogAspect {

	@DubboReference
	private ISysLogService sysLogService;

	@DubboReference
	private ISysUserService sysUserService;

	@Pointcut("@annotation(com.ztgf.sys.api.common.annotion.SysLogs)")
	public void log() {
	}

	@AfterReturning("log()")
	public void after(JoinPoint joinPoint) {
		HeadParamsBO headParamsBO = CommonParameter.getHeadParamsBO();
		SysLogSaveBO sysLog = new SysLogSaveBO();
		// 获取动作Action释义
		sysLog.setActionName(getMethodSysLogsAnnotationValue(joinPoint));
		// 获取IP
		sysLog.setIp(headParamsBO.getClientIp());
		sysLog.setUri(headParamsBO.getRequestURI());
		String s = this.paramFilter(joinPoint.getArgs());
		// 根据系统需求自定义
		sysLog.setParams(s.length() > 500 ? "数据过大，不给予记录" : s);
		sysLog.setHttpMethod(headParamsBO.getMethod());
		sysLog.setClassMethod(
		joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "()");
		//获取session的Id
		String sessionId = headParamsBO.getSessionId();
		if(StrUtils.isEmpty(sessionId)){
			return;
		}
		SysUserDTO sysUserDTO = sysUserService.getUserBySessionId(sessionId);
		if(null == sysUserDTO){
			return;
		}
		sysLog.setUsername(sysUserDTO.getAccount());
		sysLog.setUid(sysUserDTO.getId()+"");
		sysLogService.add(sysLog);
	}

	private String getMethodSysLogsAnnotationValue(JoinPoint joinPoint) {
		Signature signature = joinPoint.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();
		if (method.isAnnotationPresent(SysLogs.class)) {
			// 获取方法上注解中表明的权限
			SysLogs sysLogs = method.getAnnotation(SysLogs.class);
			return sysLogs.value();
		} else if(method.isAnnotationPresent(ApiOperation.class)){
			// 2019-05-13  xiaoc  controller可不用添加 @Syslogs注解
			ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
			return apiOperation.value();
		}
		return "未知";
	}

	private String paramFilter(Object[] params) {
		// 判断是否含有密码敏感数据
		final String filterString = "******";
		if (params.length > 0) {
			for (int i = 0; i < params.length; i++) {
				if (params[i] instanceof SysUserDTO) {
					SysUserDTO sign = (SysUserDTO) params[i];
					sign.setPassword(filterString);
					params[i] = sign;
				}
				if(params[i] instanceof MultipartFile){
					return "";
				}
			}
		}
		return JSON.toJSONString(params);
	}

}
